package com.internetCafes.spms.web.sys.service.impl;

import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.core.generic.GenericDao;
import com.internetCafes.spms.core.generic.GenericServiceImpl;
import com.internetCafes.spms.web.sys.entity.vo.MenuNavVO;
import com.internetCafes.spms.web.sys.model.MenuInfo;
import com.internetCafes.spms.web.sys.service.UserInfoService;
import com.sms.common.util.hutool.core.bean.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.internetCafes.spms.web.sys.dao.MenuInfoMapper;
import com.internetCafes.spms.web.sys.service.MenuInfoService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 菜单管理 MenuInfoService 实现类
 *
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2019-10-29 00:11:51
 */
@Service("menuInfoService")
public class MenuInfoServiceImpl extends GenericServiceImpl<MenuInfo, Long> implements MenuInfoService {

    @Autowired
    private MenuInfoMapper menuInfoMapper;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 获取用户菜单列表以及权限标签
     *
     * @param userId 用户id
     * @return 菜单列表以及权限标签
     * @author Zj
     */
    @Override
    public List<MenuNavVO> getUserMenuListAndPermissions(Long userId) {
        List<MenuInfo> menusTotal = CommonConstants.SUPER_ADMIN_ID.equals(userId) ?
                menuInfoMapper.queryAllList() : menuInfoMapper.queryAllListByUserId(userId);
        // 1-筛选出目录列表
        List<MenuNavVO> catalogMenus = menusTotal.stream()
                .filter(catalogInfo -> CommonConstants.FunctionType.CATALOG.getValue().equals(catalogInfo.getType()))
                .map(catalogInfo -> {
                    MenuNavVO catalogNavVO = new MenuNavVO();
                    BeanUtil.copyProperties(catalogInfo, catalogNavVO);
                    catalogNavVO.setList(new ArrayList<>());
                    // 1.1-筛选菜单列表
                    menusTotal.stream()
                            .filter(menuInfo -> CommonConstants.FunctionType.MENU.getValue().equals(menuInfo.getType())
                                    && catalogInfo.getMenuId().equals(menuInfo.getParentId()))
                            .forEach(menuInfoTemp -> {
                                MenuNavVO menuNavVO = new MenuNavVO();
                                BeanUtil.copyProperties(menuInfoTemp, menuNavVO);
                                // 1.1.1-筛选出权限
                                menusTotal.stream()
                                        .filter(buttonInfo -> CommonConstants.FunctionType.BUTTON.getValue().equals(buttonInfo.getType())
                                                && menuInfoTemp.getMenuId().equals(buttonInfo.getParentId()))
                                        .forEach(buttonInfoTemp -> {
                                            List<String> permCodes = parsePermCodes(buttonInfoTemp.getPerms());
                                            menuNavVO.getPermsTags().addAll(permCodes);
                                        });
                                // 1.1.2-权限标签去重
                                List<String> permTags = menuNavVO.getPermsTags().stream().distinct().collect(Collectors.toList());
                                menuNavVO.setPermsTags(permTags);
                                catalogNavVO.getList().add(menuNavVO);
                            });
                    return catalogNavVO;
                }).collect(Collectors.toList());
        return catalogMenus;
    }

    /**
     * 从数据库按钮字段权限中解析数权限编码
     *
     * @param buttonPerms 按钮权限
     * @return 解析出的权限code列表
     * @author Zj
     */
    private List<String> parsePermCodes(String buttonPerms) {
        // 解析出,前后权限
        String[] splitPerm = buttonPerms.split(",");
        List<String> perms = Arrays.asList(splitPerm);
        List<String> results = new ArrayList<>();
        perms.forEach(permTemp -> results.add(permTemp.substring(permTemp.lastIndexOf(":") + 1)));
        return results;
    }

    @Override
    public List<MenuInfo> queryListParentId(Long parentId, List<Long> menuIdList) {
        List<MenuInfo> functionList = queryListParentId(parentId);
        if (menuIdList == null) {
            return functionList;
        }

        List<MenuInfo> userFunctionList = new ArrayList<>();
        for (MenuInfo function : functionList) {
            if (menuIdList.contains(function.getMenuId())) {
                userFunctionList.add(function);
            }
        }
        return userFunctionList;
    }

    @Override
    public List<MenuInfo> queryListParentId(Long parentId) {
        return menuInfoMapper.queryListParentId(parentId);
    }

    @Override
    public List<MenuInfo> queryNotButtonList() {
        return menuInfoMapper.queryNotButtonList();
    }

    @Override
    public List<MenuInfo> getUserMenuList(Long userId) {
        //系统管理员，拥有最高权限
        if (userId == CommonConstants.SUPER_ADMIN) {
            return getAllMenuList(null);
        }

        //用户菜单列表
        List<Long> menuIdList = userInfoService.queryAllMenuId(userId);
        return getAllMenuList(menuIdList);
    }

    @Override
    public MenuInfo queryObject(Long menuId) {
        return menuInfoMapper.queryObject(menuId);
    }

    @Override
    public List<MenuInfo> queryList(Map<String, Object> map) {
        return menuInfoMapper.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return menuInfoMapper.queryTotal(map);
    }

    @Override
    public void save(MenuInfo function) {
        menuInfoMapper.save(function);
    }

    @Override
    public GenericDao<MenuInfo, Long> getDao() {
        return null;
    }

    @Override
    public int update(MenuInfo function) {
        return menuInfoMapper.update(function);
    }

    @Override
    @Transactional
    public void deleteBatch(Long[] menuIds) {
        menuInfoMapper.deleteBatch(menuIds);
    }

    @Override
    public List<MenuInfo> queryUserList(Long userId) {
        return menuInfoMapper.queryUserList(userId);
    }

    @Override
    public List<MenuInfo> list() {
        return menuInfoMapper.queryList(new HashMap<>());
    }

    @Override
    public MenuInfo getById(Long parentId) {
        return menuInfoMapper.queryObject(parentId);
    }

    @Override
    public void updateById(MenuInfo menu) {
        menuInfoMapper.update(menu);
    }

    @Override
    public void delete(long menuId) {
        menuInfoMapper.delete(menuId);
    }

    /**
     * 获取所有菜单列表
     */
    private List<MenuInfo> getAllMenuList(List<Long> menuIdList) {
        //查询根菜单列表
        List<MenuInfo> functionList = queryListParentId(0L, menuIdList);
        //递归获取子菜单
        getMenuTreeList(functionList, menuIdList);

        return functionList;
    }

    /**
     * 递归
     */
    private List<MenuInfo> getMenuTreeList(List<MenuInfo> functionList, List<Long> menuIdList) {
        List<MenuInfo> subFunctionList = new ArrayList<MenuInfo>();

        for (MenuInfo entity : functionList) {
            if (entity.getType() == CommonConstants.FunctionType.CATALOG.getValue()) {//目录
                entity.setList(getMenuTreeList(queryListParentId(entity.getMenuId(), menuIdList), menuIdList));
            }
            subFunctionList.add(entity);
        }

        return subFunctionList;
    }
}